//! API中间件模块

use std::collections::HashMap;
use std::sync::Arc;
use tokio::sync::RwLock;
use tracing::{info, warn, debug};

use super::{Request, Response};

/// CORS中间件
#[derive(Debug, Clone)]
pub struct CorsMiddleware {
    allowed_origins: Vec<String>,
    allowed_methods: Vec<String>,
    allowed_headers: Vec<String>,
}

impl CorsMiddleware {
    pub fn new() -> Self {
        Self {
            allowed_origins: vec!["*".to_string()],
            allowed_methods: vec![
                "GET".to_string(),
                "POST".to_string(),
                "PUT".to_string(),
                "DELETE".to_string(),
                "OPTIONS".to_string(),
            ],
            allowed_headers: vec![
                "Content-Type".to_string(),
                "Authorization".to_string(),
                "X-Requested-With".to_string(),
            ],
        }
    }

    pub fn with_allowed_origins(mut self, origins: Vec<String>) -> Self {
        self.allowed_origins = origins;
        self
    }

    pub fn with_allowed_methods(mut self, methods: Vec<String>) -> Self {
        self.allowed_methods = methods;
        self
    }

    pub fn with_allowed_headers(mut self, headers: Vec<String>) -> Self {
        self.allowed_headers = headers;
        self
    }
}

#[async_trait::async_trait]
impl super::MiddlewareTrait for CorsMiddleware {
    async fn process(&self, request: Request) -> Result<Request, Box<dyn std::error::Error + Send + Sync>> {
        if request.method == "OPTIONS" {
            return Err(Box::new(std::io::Error::new(
                std::io::ErrorKind::Other,
                "CORS preflight",
            )));
        }
        Ok(request)
    }
}

/// 限流中间件
#[derive(Debug, Clone)]
pub struct RateLimitMiddleware {
    requests_per_second: u64,
    requests: Arc<RwLock<HashMap<String, RateLimitData>>>,
}

#[derive(Debug, Clone)]
struct RateLimitData {
    count: u64,
    window_start: std::time::Instant,
}

impl RateLimitMiddleware {
    pub fn new(requests_per_second: u64) -> Self {
        Self {
            requests_per_second,
            requests: Arc::new(RwLock::new(HashMap::new())),
        }
    }

    fn get_client_key(&self, request: &Request) -> String {
        request.remote_addr.clone()
    }

    async fn check_rate_limit(&self, client_key: &str) -> bool {
        let mut requests = self.requests.write().await;
        let now = std::time::Instant::now();
        let window_duration = std::time::Duration::from_secs(1);

        let data = requests
            .entry(client_key.to_string())
            .or_insert(RateLimitData {
                count: 0,
                window_start: now,
            });

        if now.duration_since(data.window_start) >= window_duration {
            data.count = 0;
            data.window_start = now;
        }

        if data.count >= self.requests_per_second {
            return false;
        }

        data.count += 1;
        true
    }
}

#[async_trait::async_trait]
impl super::MiddlewareTrait for RateLimitMiddleware {
    async fn process(&self, request: Request) -> Result<Request, Box<dyn std::error::Error + Send + Sync>> {
        let client_key = self.get_client_key(&request);
        
        if !self.check_rate_limit(&client_key).await {
            warn!("Rate limit exceeded for client: {}", client_key);
            return Err(Box::new(std::io::Error::new(
                std::io::ErrorKind::Other,
                "Rate limit exceeded",
            )));
        }

        Ok(request)
    }
}

/// 认证中间件
#[derive(Debug, Clone)]
pub struct AuthMiddleware {
    valid_tokens: Arc<RwLock<HashMap<String, TokenInfo>>>,
}

#[derive(Debug, Clone)]
struct TokenInfo {
    user_id: String,
    username: String,
    expires_at: chrono::DateTime<chrono::Utc>,
}

impl AuthMiddleware {
    pub fn new() -> Self {
        Self {
            valid_tokens: Arc::new(RwLock::new(HashMap::new())),
        }
    }

    pub async fn add_token(&self, token: String, user_id: String, username: String, expires_at: chrono::DateTime<chrono::Utc>) {
        let mut tokens = self.valid_tokens.write().await;
        tokens.insert(token, TokenInfo {
            user_id,
            username,
            expires_at,
        });
    }

    pub async fn remove_token(&self, token: &str) {
        let mut tokens = self.valid_tokens.write().await;
        tokens.remove(token);
    }

    async fn validate_token(&self, token: &str) -> Option<TokenInfo> {
        let tokens = self.valid_tokens.read().await;
        if let Some(token_info) = tokens.get(token) {
            if token_info.expires_at > chrono::Utc::now() {
                return Some(token_info.clone());
            }
        }
        None
    }

    fn extract_token(&self, request: &Request) -> Option<String> {
        if let Some(auth_header) = request.headers.get("Authorization") {
            if auth_header.starts_with("Bearer ") {
                return Some(auth_header[7..].to_string());
            }
        }
        None
    }
}

#[async_trait::async_trait]
impl super::MiddlewareTrait for AuthMiddleware {
    async fn process(&self, request: Request) -> Result<Request, Box<dyn std::error::Error + Send + Sync>> {
        // 跳过健康检查等公开接口
        if request.path.starts_with("/health") || request.path.starts_with("/metrics") {
            return Ok(request);
        }

        let token = self.extract_token(&request)
            .ok_or_else(|| Box::new(std::io::Error::new(
                std::io::ErrorKind::PermissionDenied,
                "Missing authorization token",
            )))?;

        let token_info = self.validate_token(&token).await
            .ok_or_else(|| Box::new(std::io::Error::new(
                std::io::ErrorKind::PermissionDenied,
                "Invalid or expired token",
            )))?;

        info!("Authenticated request from user: {}", token_info.username);

        Ok(request)
    }
}

/// 日志中间件
#[derive(Debug, Clone)]
pub struct LoggingMiddleware {
    log_requests: bool,
    log_responses: bool,
}

impl LoggingMiddleware {
    pub fn new() -> Self {
        Self {
            log_requests: true,
            log_responses: true,
        }
    }

    pub fn with_log_requests(mut self, log_requests: bool) -> Self {
        self.log_requests = log_requests;
        self
    }

    pub fn with_log_responses(mut self, log_responses: bool) -> Self {
        self.log_responses = log_responses;
        self
    }
}

#[async_trait::async_trait]
impl super::MiddlewareTrait for LoggingMiddleware {
    async fn process(&self, request: Request) -> Result<Request, Box<dyn std::error::Error + Send + Sync>> {
        if self.log_requests {
            info!(
                "Request: {} {} from {}",
                request.method, request.path, request.remote_addr
            );
            debug!("Headers: {:?}", request.headers);
        }
        Ok(request)
    }

}

/// 请求ID中间件
#[derive(Debug, Clone)]
pub struct RequestIdMiddleware;

#[async_trait::async_trait]
impl super::MiddlewareTrait for RequestIdMiddleware {
    async fn process(&self, mut request: Request) -> Result<Request, Box<dyn std::error::Error + Send + Sync>> {
        let request_id = uuid::Uuid::new_v4().to_string();
        request.headers.insert("X-Request-ID".to_string(), request_id.clone());
        info!("Request ID: {}", request_id);
        Ok(request)
    }

}

/// 请求超时中间件
#[derive(Debug, Clone)]
pub struct TimeoutMiddleware {
    timeout_duration: std::time::Duration,
}

impl TimeoutMiddleware {
    pub fn new(timeout_seconds: u64) -> Self {
        Self {
            timeout_duration: std::time::Duration::from_secs(timeout_seconds),
        }
    }
}

#[async_trait::async_trait]
impl super::MiddlewareTrait for TimeoutMiddleware {
    async fn process(&self, request: Request) -> Result<Request, Box<dyn std::error::Error + Send + Sync>> {
        // 这里的超时处理将在上层路由中实现
        Ok(request)
    }
}

/// 中间件链
pub struct MiddlewareChain {
    middlewares: Vec<super::Middleware>,
}

impl MiddlewareChain {
    pub fn new() -> Self {
        Self {
            middlewares: Vec::new(),
        }
    }

    pub fn add_middleware(mut self, middleware: super::Middleware) -> Self {
        self.middlewares.push(middleware);
        self
    }

    pub async fn process_request(&self, mut request: Request) -> Result<Request, Box<dyn std::error::Error + Send + Sync>> {
        for middleware in &self.middlewares {
            request = middleware.process(request).await?;
        }
        Ok(request)
    }

    pub fn process_response(&self, mut response: Response) -> Response {
        for middleware in &self.middlewares {
            match middleware {
                super::Middleware::Cors(_) => {
                    // TODO: Implement response processing for CORS
                }
                super::Middleware::Logging(_) => {
                    // TODO: Implement response processing for Logging
                }
                _ => {}
            }
        }
        response
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use tokio::time::sleep;

    #[tokio::test]
    async fn test_rate_limit_middleware() {
        let middleware = RateLimitMiddleware::new(2);
        let request = Request {
            method: "GET".to_string(),
            path: "/test".to_string(),
            headers: HashMap::new(),
            query_params: HashMap::new(),
            body: vec![],
            remote_addr: "127.0.0.1".to_string(),
        };

        // 前两个请求应该成功
        assert!(middleware.process(request.clone()).await.is_ok());
        assert!(middleware.process(request.clone()).await.is_ok());

        // 第三个请求应该被限流
        assert!(middleware.process(request).await.is_err());
    }

    #[tokio::test]
    async fn test_auth_middleware() {
        let middleware = AuthMiddleware::new();
        let request = Request {
            method: "GET".to_string(),
            path: "/protected".to_string(),
            headers: [("Authorization".to_string(), "Bearer valid-token".to_string())]
                .iter()
                .cloned()
                .collect(),
            query_params: HashMap::new(),
            body: vec![],
            remote_addr: "127.0.0.1".to_string(),
        };

        // 由于token无效，应该失败
        assert!(middleware.process(request).await.is_err());
    }

    #[tokio::test]
    async fn test_cors_middleware() {
        let middleware = CorsMiddleware::new();
        let response = Response {
            status_code: 200,
            headers: HashMap::new(),
            body: vec![],
        };

        let processed_response = middleware.process_response(response);
        assert!(processed_response.headers.contains_key("Access-Control-Allow-Origin"));
    }
}